/*
 * Copyright (c) 2010 Andy Aspell-Clark
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */
package uk.org.aspellclark.agenedb;

import java.io.File;
import java.util.List;
import java.util.StringTokenizer;

import org.openintents.intents.AboutIntents;
import org.openintents.intents.FileManagerIntents;

import uk.org.aspellclark.agenedb.controller.ChangeDateController;
import uk.org.aspellclark.agenedb.controller.Db4oController;
import uk.org.aspellclark.agenedb.controller.FamilyController;
import uk.org.aspellclark.agenedb.controller.GedcomController;
import uk.org.aspellclark.agenedb.controller.HeaderController;
import uk.org.aspellclark.agenedb.controller.IndividualController;
import uk.org.aspellclark.agenedb.controller.MultimediaController;
import uk.org.aspellclark.agenedb.db.DatabaseObjectContainer;
import uk.org.aspellclark.agenedb.gedcom.model.Family;
import uk.org.aspellclark.agenedb.gedcom.model.Individual;
import uk.org.aspellclark.agenedb.gedcom.parser.GedcomParser;
import uk.org.aspellclark.agenedb.view.EditPreferences;
import uk.org.aspellclark.agenedb.view.GedcomFileInformationView;
import uk.org.aspellclark.agenedb.view.GedcomTreeView;
import uk.org.aspellclark.agenedb.view.IndividualDetailsView;
import uk.org.aspellclark.agenedb.view.family.FamiliesListRowAdapter;
import uk.org.aspellclark.agenedb.view.individual.IndividualListRowAdapter;
import uk.org.aspellclark.common.CommonFunctions;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class AGeneDb extends Activity implements OnItemClickListener {

	private static final String LAUNCHPAD_TRANSLATOR_CREDITS_SEPARATOR = ";";
	private static final String LAUNCHPAD_TRANSLATOR_CREDITS_REGEX = "(" + LAUNCHPAD_TRANSLATOR_CREDITS_SEPARATOR
			+ " )|(" + LAUNCHPAD_TRANSLATOR_CREDITS_SEPARATOR + ")";
	private static final String LAUNCHPAD_TRANSLATOR_CREDITS_HEADER = "Launchpad Contributions: ";
	private static final String LAUNCHPAD_TRANSLATOR_CREDITS_TAG = "translator-credits";

	private static final String PREFS_NAME = "AGeneDBPrefs";
	private static final int REQUEST_CODE_PICK_FILE_OR_DIRECTORY = 1;
	private static final int ID_DIALOG_PROGRESS_IMPORT = 987;
	private static final int ID_DIALOG_PROGRESS_POPULATE_LIST = 988;

	private static String gedcomFileDirectory = "gedcom";
	private static String gedcomImageFileDir = "images";

	private static String LOG_TAG = "AGeneDB";

	public static String getGedomImagePathDir() {
		final File extDir = Environment.getExternalStorageDirectory();
		return extDir.getPath() + File.separator + AGeneDb.gedcomFileDirectory + File.separator + gedcomImageFileDir
				+ File.separator;
	}

	public static String getGedomPathDir() {
		final File extDir = Environment.getExternalStorageDirectory();
		return extDir.getPath() + File.separator + AGeneDb.gedcomFileDirectory + File.separator;
	}

	private String gedcomFilename = "";
	private String extDirStr;

	private ProgressDialog loadingDialog;

	private GedcomParser gedcomParser = GedcomParser.getParser();

	public final Handler handler = new Handler() {
		@Override
		public void handleMessage(final Message msg) {
			AGeneDb.this.loadingDialog.setProgress(msg.what);
		}
	};

	/**
	 * @return
	 */
	private String getPayPalDonateName() {
		return "AGeneDB";
	}

	/**
	 * this method displays a progress dialog while it is performing the 'Long
	 * Process' of importing the gedcom file
	 */
	private void importGedcomFile(final String gedcomFname) {

		this.showDialog(ID_DIALOG_PROGRESS_IMPORT);

		final File gedcomFile = new File(gedcomFname);
		if (!gedcomFile.exists()) {
			Toast.makeText(AGeneDb.this, R.string.fileNotFound, Toast.LENGTH_SHORT).show();
			return;
		}
		this.gedcomFilename = gedcomFname;
		this.gedcomParser.setGedcomFilename(AGeneDb.this.gedcomFilename);

		final Thread importGedcomFileThread = new Thread() {
			@Override
			public void run() {
				// *** Your Long Calculation (Or Other) Goes Here

				try {
					AGeneDb.this.gedcomParser.parse(AGeneDb.this.handler);

				} catch (final Exception e) {
					Log.e(LOG_TAG, e.getMessage());
					// Toast.makeText(AGeneDb.this, R.string.fileImportFailure,Toast.LENGTH_SHORT).show();
				}

				final Runnable updateListsAfterImport = new Runnable() {
					public void run() {
						AGeneDb.this.removeDialog(ID_DIALOG_PROGRESS_IMPORT);
						try {
							if (!AGeneDb.this.gedcomParser.errors.isEmpty()) {
								Toast.makeText(AGeneDb.this, R.string.fileImportWithErrors, Toast.LENGTH_LONG).show();
								for (String msgStr : AGeneDb.this.gedcomParser.errors) {
									Log.e("AGeneDB Gedcom Parsring Error", msgStr);
								}
							} else if (!AGeneDb.this.gedcomParser.warnings.isEmpty()) {
								Toast.makeText(AGeneDb.this, R.string.fileImportWithWarnings, Toast.LENGTH_LONG).show();
							} else {
								Toast.makeText(AGeneDb.this, R.string.fileImportSuccess, Toast.LENGTH_SHORT).show();
							}
							AGeneDb.this.updateIndividualList();
							AGeneDb.this.preferencesSave(true);
						} catch (Throwable t) {
							//Store error and informa user!!
							Log.e(LOG_TAG, t.getMessage());
						}
						AGeneDb.this.setTitle("AGeneDB (" + AGeneDb.this.gedcomFilename + ")");
					}
				};
				// Run the thread
				AGeneDb.this.runOnUiThread(updateListsAfterImport);

				// *** Long Calculation ends here
				//handler.sendEmptyMessage(-1);
				//AGeneDb.this.dismissDialog(ID_DIALOG_PROGRESS);
			}
		};
		importGedcomFileThread.setName("GedcomImport");
		importGedcomFileThread.start();
	}

	/**
	 * This is called after the user has selected a file in the file manager
	 * activity.
	 */
	@Override
	protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		switch (requestCode) {
		case REQUEST_CODE_PICK_FILE_OR_DIRECTORY:
			if (resultCode == RESULT_OK && data != null) {
				// obtain the filename
				this.gedcomFilename = data.getDataString();
				if (this.gedcomFilename != null) {
					// Get rid of URI prefix:
					if (this.gedcomFilename.startsWith("file://")) {
						this.gedcomFilename = this.gedcomFilename.substring(7);
					}
					this.gedcomFilename = this.gedcomFilename.replace("%20", " ");
					this.importGedcomFile(this.gedcomFilename);
				}
			}
			break;
		}
	}

	/**
	 * Called when the activity is first created.
	 */
	@Override
	public void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.individuals_list_view);

		DatabaseObjectContainer.dbCntrlr = new Db4oController(this);
		DatabaseObjectContainer.dbCntrlr.openDatabase();

		DatabaseObjectContainer.gedcomCntrlr = new GedcomController(DatabaseObjectContainer.dbCntrlr);
		DatabaseObjectContainer.headerCntrlr = new HeaderController(DatabaseObjectContainer.dbCntrlr);
		DatabaseObjectContainer.familyCntrlr = new FamilyController(DatabaseObjectContainer.dbCntrlr);
		DatabaseObjectContainer.individualCntrlr = new IndividualController(DatabaseObjectContainer.dbCntrlr);
		DatabaseObjectContainer.multimediaCntrlr = new MultimediaController(DatabaseObjectContainer.dbCntrlr);
		DatabaseObjectContainer.changeDateCntrlr = new ChangeDateController(DatabaseObjectContainer.dbCntrlr);

		// check that OI file manager is installed. if not go to the market
		// so that the user can install it.
		final boolean fileAvailable = CommonFunctions.isIntentAvailable(this, FileManagerIntents.ACTION_PICK_FILE);
		if (!fileAvailable) {
			Intent marketLaunch = new Intent(Intent.ACTION_VIEW);
			String srchStr = "market://search?q=" + "org.openintents.filemanager";
			marketLaunch.setData(Uri.parse(srchStr));
			Toast.makeText(this, R.string.oifilemanager_pleaseinstall, Toast.LENGTH_SHORT).show();
			this.startActivity(marketLaunch);
		}

		this.extDirStr = AGeneDb.getGedomPathDir();
		//MultimediaController.getInstance().setGedomPathDir(this.extDirStr);

		try {
			this.dismissDialog(ID_DIALOG_PROGRESS_IMPORT);
			this.dismissDialog(ID_DIALOG_PROGRESS_POPULATE_LIST);
		} catch (Exception e) {
			Log.e(LOG_TAG, e.getMessage());
		}

		this.preferencesRestore();
		this.updateIndividualListOnThread();
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		if (id == ID_DIALOG_PROGRESS_IMPORT) {
			this.loadingDialog = new ProgressDialog(this);
			this.loadingDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			this.loadingDialog.setTitle(this.getString(R.string.PleaseWait));
			this.loadingDialog.setMessage(this.getString(R.string.LoadingGedcomFile));
			this.loadingDialog.setIndeterminate(false);
			this.loadingDialog.setCancelable(true);
			File f = new File(this.gedcomFilename);
			this.loadingDialog.setMax((int) f.length());
			this.loadingDialog.setProgress(0);
			return this.loadingDialog;
		}
		if (id == ID_DIALOG_PROGRESS_POPULATE_LIST) {
			this.loadingDialog = new ProgressDialog(this);
			this.loadingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			this.loadingDialog.setTitle(this.getString(R.string.PleaseWait));
			this.loadingDialog.setMessage(this.getString(R.string.LoadingListItems));
			this.loadingDialog.setIndeterminate(true);
			this.loadingDialog.setCancelable(true);
			return this.loadingDialog;
		}

		return super.onCreateDialog(id);
	}

	@Override
	public boolean onCreateOptionsMenu(final Menu menu) {
		final boolean retValue = super.onCreateOptionsMenu(menu);
		//this.theMenu = menu;
		new MenuInflater(this.getApplication()).inflate(R.menu.mainmenu, menu);
		return retValue;
	}

	@Override
	public void onItemClick(AdapterView<?> arg0, View childView, int arg2, long arg3) {
		TextView tmpView = (TextView) childView;
		String prsnName = tmpView.getText().toString();

		// get person id from string
		StringTokenizer tok = new StringTokenizer(prsnName, "[");
		String idStr = tok.nextToken();
		idStr = tok.nextToken();
		if (idStr.endsWith("]")) {
			idStr = idStr.substring(0, idStr.length() - 1);
		}

		AGeneDb.this.updateCurrentPerson(idStr);
	}

	public void onItemSelected(final AdapterView<?> parent, final View v, final int position, final long id) {
		// uk.org.aspellclark.common.logging.Logger.d("AGeneDB",
		// "onItemSelected()");
	}

	public void onNothingSelected(final AdapterView<?> parent) {
		// uk.org.aspellclark.common.logging.Logger.d("AGeneDB",
		// "onNothingSelected()");
	}

	/**
	 * this function is called when the user selects a menu item from the options
	 * menu.
	 */
	@Override
	public boolean onOptionsItemSelected(final MenuItem item) {
		boolean retvalue = false;
		if (item.getItemId() == R.id.menu_selectGedcomFile) {
			this.selectGedcomFile();
			retvalue = true;
		} else if (item.getItemId() == R.id.menu_aboutAGeneDB) {
			this.showAboutdialog();
			retvalue = true;
		} else if (item.getItemId() == R.id.menu_settings) {
			this.startActivity(new Intent(this.getBaseContext(), EditPreferences.class));
			//Toast.makeText(this, R.string.notImplementedYet, Toast.LENGTH_SHORT).show();
			retvalue = true;
		} else if (item.getItemId() == R.id.menu_gedcomFileInfo) {
			try {
				this.startActivity(new Intent(this.getBaseContext(), GedcomFileInformationView.class));
			} catch (Exception e) {
				e.printStackTrace();
			}
			retvalue = true;
		} else if (item.getItemId() == R.id.menu_help) {
			try {
				this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(this
						.getString(R.string.about_website_userguide_url))));
			} catch (Exception e) {
				e.printStackTrace();
			}
			retvalue = true;
		} else if (item.getItemId() == R.id.menu_quit) {
			this.finish();
			retvalue = true;
		} else if (item.getItemId() == R.id.menu_donate) {
			try {
				String paypalLink = "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=9G2LQH6GBQSLW&lc=GB&item_name="
						+ this.getPayPalDonateName()
						+ "&currency_code=GBP&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted";
				this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(paypalLink)));
			} catch (final Exception e) {
				Log.e(LOG_TAG, e.getMessage());
			}
			retvalue = true;
		}
		return retvalue;
	}

	@Override
	protected void onPause() {
		try {
			DatabaseObjectContainer.dbCntrlr.closeDatabase();
			this.dismissDialog(ID_DIALOG_PROGRESS_IMPORT);
			this.dismissDialog(ID_DIALOG_PROGRESS_POPULATE_LIST);
		} catch (Exception e) {
			Log.e(LOG_TAG, e.getMessage());
		}
		this.preferencesSave(true);
		DatabaseObjectContainer.dbCntrlr.openDatabase();
		super.onPause();
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		final boolean aboutAvailable = CommonFunctions.isIntentAvailable(this, AboutIntents.ACTION_SHOW_ABOUT_DIALOG);
		MenuItem item;
		item = menu.findItem(R.id.menu_aboutAGeneDB);
		item.setEnabled(aboutAvailable);

		final boolean fileAvailable = CommonFunctions.isIntentAvailable(this, FileManagerIntents.ACTION_PICK_FILE);
		item = menu.findItem(R.id.menu_selectGedcomFile);
		item.setEnabled(fileAvailable);

		return super.onPrepareOptionsMenu(menu);
	}

	private void preferencesRestore() {
		final SharedPreferences settings = this.getSharedPreferences(PREFS_NAME, 0);
		this.gedcomFilename = settings.getString("lastGedcomFilename", "");
		DatabaseObjectContainer.individualCntrlr.setCurrentPrsnId(settings.getString("currentPersonId", ""));

		this.preferencesSave(true);
	}

	private void preferencesSave(boolean closeSuccess) {
		// Save user preferences. We need an Editor object to
		// make changes. All objects are from android.context.Context
		final SharedPreferences settings = this.getSharedPreferences(PREFS_NAME, 0);
		final SharedPreferences.Editor editor = settings.edit();
		editor.putBoolean(EditPreferences.PREF_CLOSED_SUCCESSFULLY, closeSuccess);
		editor.putString(EditPreferences.PREF_LOAD_LAST_FILENAME, this.gedcomFilename);
		editor.putString(EditPreferences.PREF_CURRENT_PERSON_ID, DatabaseObjectContainer.individualCntrlr
				.getCurrentPrsnId());

		// Don't forget to commit your edits!!!
		editor.commit();
	}

	/**
	 * this function starts the file picker activity.
	 */
	private void selectGedcomFile() {
		Intent filePickerIntent = new Intent(FileManagerIntents.ACTION_PICK_FILE);
		final Uri gedcomDirUri = Uri.fromFile(new File(this.extDirStr));
		filePickerIntent.setData(gedcomDirUri);

		// Set fancy title and button (optional)
		filePickerIntent.putExtra(FileManagerIntents.EXTRA_TITLE, this.getString(R.string.open_title));
		filePickerIntent.putExtra(FileManagerIntents.EXTRA_BUTTON_TEXT, this.getString(R.string.open_button));

		try {
			this.startActivityForResult(filePickerIntent, REQUEST_CODE_PICK_FILE_OR_DIRECTORY);
		} catch (final ActivityNotFoundException e) {
			// No compatible file manager was found.
			Toast.makeText(this, R.string.oifilemanager_installed, Toast.LENGTH_SHORT).show();
		}
	}

	/**
	 * Show an about dialog for this application.
	 */
	private void showAboutdialog() {
		try {

			final Intent aboutDlgIntnt = new Intent(AboutIntents.ACTION_SHOW_ABOUT_DIALOG);

			aboutDlgIntnt.putExtra(AboutIntents.EXTRA_PACKAGE_NAME, this.getPackageName());

			// Supply the image.
			/*
			 * //alternative 1: Put the image resId into the provider. Bitmap image =
			 * BitmapFactory.decodeResource(getResources(), R.drawable.icon);//lossy
			 * String uri = Images.Media.insertImage(getContentResolver(), image,
			 * getString(R.string.about_logo_title),
			 * getString(R.string.about_logo_description));
			 * intent.putExtra(AboutIntents.EXTRA_ICON_URI, uri);
			 */

			// alternative 2: Supply the image name and package.
			aboutDlgIntnt.putExtra(AboutIntents.EXTRA_ICON_RESOURCE, this.getResources().getResourceName(
					R.drawable.ic_menu_info_details));

			aboutDlgIntnt.putExtra(AboutIntents.EXTRA_APPLICATION_LABEL, this.getString(R.string.app_name));

			// Get the app version
			String version = "?";
			try {
				final PackageInfo pi = this.getPackageManager().getPackageInfo(this.getPackageName(), 0);
				version = pi.versionName;
			} catch (final PackageManager.NameNotFoundException e) {
				uk.org.aspellclark.common.logging.Logger.e("ShowAboutWithExtras", "Package name not found", e);
			}
			aboutDlgIntnt.putExtra(AboutIntents.EXTRA_VERSION_NAME, version);

			aboutDlgIntnt.putExtra(AboutIntents.EXTRA_COMMENTS, this.getString(R.string.about_comments));
			aboutDlgIntnt.putExtra(AboutIntents.EXTRA_COPYRIGHT, this.getString(R.string.about_copyright));
			aboutDlgIntnt.putExtra(AboutIntents.EXTRA_WEBSITE_LABEL, this.getString(R.string.about_website_label));
			aboutDlgIntnt.putExtra(AboutIntents.EXTRA_WEBSITE_URL, this.getString(R.string.about_website_url));
			aboutDlgIntnt
					.putExtra(AboutIntents.EXTRA_AUTHORS, this.getResources().getStringArray(R.array.about_authors));
			aboutDlgIntnt.putExtra(AboutIntents.EXTRA_DOCUMENTERS, this.getResources().getStringArray(
					R.array.about_documenters));

			// Create string array of translators from translated string from
			// Launchpad
			// or (for English) from the array.
			final String translatorsString = this.getString(R.string.about_translators);
			if (translatorsString.equals(LAUNCHPAD_TRANSLATOR_CREDITS_TAG)) {
				aboutDlgIntnt.putExtra(AboutIntents.EXTRA_TRANSLATORS, this.getResources().getStringArray(
						R.array.about_translators));
			} else {
				final String[] translatorsArray = translatorsString.replaceFirst(LAUNCHPAD_TRANSLATOR_CREDITS_HEADER, "")
						.split(LAUNCHPAD_TRANSLATOR_CREDITS_REGEX);
				aboutDlgIntnt.putExtra(AboutIntents.EXTRA_TRANSLATORS, translatorsArray);
			}

			aboutDlgIntnt
					.putExtra(AboutIntents.EXTRA_ARTISTS, this.getResources().getStringArray(R.array.about_helpers));

			// Supply resource name of raw resource that contains the license:
			aboutDlgIntnt.putExtra(AboutIntents.EXTRA_LICENSE_RESOURCE, this.getResources().getResourceName(
					R.raw.license_short));

			/*
			 * //Read in the license file as a big String BufferedReader in = new
			 * BufferedReader(new InputStreamReader(
			 * getResources().openRawResource(R.raw.license_short))); String license =
			 * ""; String line; try { while ((line = in.readLine()) != null) { // Read
			 * line per line. license += line + "\n"; } } catch (IOException e) {
			 * //Should not happen. e.printStackTrace(); }
			 * intent.putExtra(AboutIntents.EXTRA_LICENSE, license);
			 * intent.putExtra(AboutIntents.EXTRA_WRAP_LICENSE, false);
			 */

			// Start about activity. Needs to be "forResult" with requestCode>=0
			// because the About dialog may call elements from your Manifest by your
			// package name.
			this.startActivityForResult(aboutDlgIntnt, 0);

		} catch (final ActivityNotFoundException e) {
			Toast.makeText(this, R.string.oiabout_installed, Toast.LENGTH_SHORT).show();
		}
	}

	public void showTreeView() {
		Intent intnt = new Intent(this.getBaseContext(), GedcomTreeView.class);
		this.startActivity(intnt);
	}

	/**
	 * stores the currently selected person.
	 * 
	 * @param prsnId
	 */
	public void updateCurrentPerson(final String prsnId) {
		try {
			if (prsnId.length() > 0) {
				// update currently selected person
				//this.gedcomParser.gedcom.currentPrsnId = prsnId;
				DatabaseObjectContainer.individualCntrlr.setCurrentPrsnId(prsnId);

				this.startActivity(new Intent(this.getBaseContext(), IndividualDetailsView.class));
			}
		} catch (final Exception e) {
			Log.e(LOG_TAG, e.getMessage());
		}
	}

	/**
	 * This function populates the families list with the data from the loaded
	 * gedcom file.
	 */
	private void updateFamiliesList() {

		// start tracing to "/sdcard/updateFamiliesList.trace"
		//Debug.startMethodTracing("updateFamiliesList");

		try {
			ListView familyList = (ListView) this.findViewById(R.id.familiesListView);

			List<Family> fams = DatabaseObjectContainer.familyCntrlr.getFamilies();
			FamiliesListRowAdapter rowAdapter = new FamiliesListRowAdapter(this, R.layout.families_list_view_row, fams);

			//FIXME : rowAdapter.sort(new FamilyNameComparator());
			familyList.setAdapter(rowAdapter);
			rowAdapter.notifyDataSetChanged();

			familyList.requestLayout();
		} catch (final Exception e) {
			Log.e(LOG_TAG, e.getMessage());
			//Toast.makeText(this, "Exception Caught creating Families list", Toast.LENGTH_SHORT).show();
		}

		// stop tracing
		//Debug.stopMethodTracing();
	}

	/**
	 * This function populates the individuals list with the data from the loaded
	 * gedcom file.
	 */
	private void updateIndividualList() {

		// start tracing to "/sdcard/updateIndividualList.trace"
		//Debug.startMethodTracing("updateIndividualList");

		try {
			List<Individual> individs = DatabaseObjectContainer.individualCntrlr.getIndividuals();

			IndividualListRowAdapter indivAdapter = new IndividualListRowAdapter(this,
					R.layout.individuals_list_view_row, individs);

			ListView lstView = (ListView) this.findViewById(R.id.individualsListView);
			//indivAdapter.sort(new IndividualSurnameNameComparator());
			lstView.setAdapter(indivAdapter);
			indivAdapter.notifyDataSetChanged();

			lstView.requestLayout();
		} catch (Exception e) {
			Log.e(LOG_TAG, e.getMessage());
			//Toast.makeText(this, "Exception Caught creating Individuals List", Toast.LENGTH_SHORT).show();
		}

		// stop tracing
		//Debug.stopMethodTracing();
	}

	/**
	 * this method displays a progress dialog while it is performing the 'Long
	 * Process' of importing the gedcom file
	 */
	private void updateIndividualListOnThread() {
		List<Individual> individs = DatabaseObjectContainer.individualCntrlr.getIndividuals();

		if (individs.size() == 0) {
			//this.selectGedcomFile();
			return;
		}
		this.showDialog(ID_DIALOG_PROGRESS_POPULATE_LIST);

		final Thread updateListThread = new Thread() {
			@Override
			public void run() {
				try {
					AGeneDb.this.updateIndividualList();
				} catch (final Exception e) {
					Log.e(LOG_TAG, e.getMessage());
					// Toast.makeText(AGeneDb.this, R.string.fileImportFailure,Toast.LENGTH_SHORT).show();
				}

				final Runnable updateListsAfterImport = new Runnable() {
					public void run() {
						AGeneDb.this.removeDialog(ID_DIALOG_PROGRESS_POPULATE_LIST);
					}
				};
				// Run the thread
				AGeneDb.this.runOnUiThread(updateListsAfterImport);
			}
		};
		updateListThread.setName("UpdateTree");
		updateListThread.start();
	}
}
